#include "common.h"

#include "slider.h"
#include "button.h"
#include "text.h"
#include "xplane.h"

typedef struct xplane_state_ /*{{{*/
{
	SDL_Surface* screen;	

	slider throttle;
	button reverse;

	slider trim;
	button center_trim;

	slider flaps;

	button hold_center;
	button gear_up;
	button gear_down;
	button brakes;

	text ip;

	int sock;
	struct sockaddr dest;
} xplane_state; /*}}}*/

void display(xplane_state* state);

int main(int argc, char** argv) /*{{{*/
{
	int ret;
	xplane_state state;
	memset(&state, 0, sizeof(xplane_state));

	// init sdl
	ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
	TTF_Init();
	SDL_Joystick* joystick = SDL_JoystickOpen(0);
	state.screen = SDL_SetVideoMode(480, 320, 0, SDL_FULLSCREEN);
	SDL_EnableUNICODE(1);

	// init net
	state.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	struct sockaddr_in* dest_in = (struct sockaddr_in*)&state.dest;
	memset(&state.dest, 0, sizeof(state.dest));
	dest_in->sin_family = AF_INET;
	dest_in->sin_port = htons(49000);
	inet_pton(AF_INET, "127.0.0.1", &(dest_in->sin_addr.s_addr));

	// init widgets
	init_slider(&state.throttle, "Throttle", 360, 20, 10, 230, 0.0);
	init_button(&state.reverse, "Reverse", 335, 290, 60, 30, 1);

	init_slider(&state.trim, "Trim", 280, 20, 10, 230, 0.5);
	init_button(&state.center_trim, "Center", 255, 290, 60, 30, 0);

	init_slider(&state.flaps, "Flaps", 200, 20, 10, 230, 0);
	set_slider_fraction(&state.flaps, 1.0);

	init_button(&state.hold_center, "Hold center", 20, 30, 90, 60, 1);
	init_button(&state.gear_up, "Gear up", 20, 115, 90, 30, 0);
	init_button(&state.gear_down, "Gear down", 20, 145, 90, 30, 0);
	init_button(&state.brakes, "Brakes", 20, 170, 90, 60, 0);

	init_text(&state.ip, "Type X-Plane host's IP", 440, 60, 30, 60);

	display(&state);

	SDL_Event event;
	while (1)
	{
		while (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
				case SDL_KEYDOWN:         
					input_text(&state.ip, event.key.keysym.unicode);
					inet_pton(AF_INET, state.ip.str, &(dest_in->sin_addr.s_addr));
					display(&state);
					break;
				case SDL_MOUSEBUTTONDOWN:
					touch_button(&state.hold_center, event.motion.x, event.motion.y);
					if (touch_button(&state.reverse, event.motion.x, event.motion.y))
					{
						float throttle = get_slider_fraction(&state.throttle);
						if (get_button_toggled(&state.reverse))
							throttle = -throttle;
						set_throttle(state.sock, 
							&state.dest, 
							throttle);
					}
					display(&state);
					break;
				case SDL_MOUSEBUTTONUP:
					set_button_toggled(&state.gear_up, 0);
					set_button_toggled(&state.gear_down, 0);
					set_button_toggled(&state.brakes, 0);
					set_button_toggled(&state.center_trim, 0);
					set_gear_brakes(state.sock,
								&state.dest, -999.0, 0.0);
					display(&state);
					break;
				case SDL_MOUSEMOTION:        
					if (touch_slider(&state.throttle, event.motion.x, event.motion.y))
					{
						float throttle = get_slider_fraction(&state.throttle);
						if (get_button_toggled(&state.reverse))
							throttle = -throttle;
						set_throttle(state.sock, 
							&state.dest, 
							throttle);
					}

					int force_trim = 0;
					if (touch_button(&state.center_trim, event.motion.x, event.motion.y))
					{
						set_slider_fraction(&state.trim, 0.5);
						force_trim = 1;
					}

					if (force_trim ||
						touch_slider(&state.flaps, event.motion.x, event.motion.y) || 
						touch_slider(&state.trim, event.motion.x, event.motion.y))
						set_trim_flaps(state.sock, &state.dest, -((2.0*get_slider_fraction(&state.trim))-1.0),
						1.0-get_slider_fraction(&state.flaps));

										float gear = -999.0, brakes = -999.0;
					if (touch_button(&state.gear_up, event.motion.x, event.motion.y) ||
						touch_button(&state.gear_down, event.motion.x, event.motion.y))
					{
						if (get_button_toggled(&state.gear_up))
							gear = 0.0;
						if (get_button_toggled(&state.gear_down))
							gear = 1.0;
					}
					if (touch_button(&state.brakes, event.motion.x, event.motion.y))
						brakes = 1.0; 
					else 
						brakes = 0.0;	
					set_gear_brakes(state.sock,
								&state.dest, gear, brakes);
					display(&state);
					break;
			}
		}

		float joy_x, joy_y, joy_z;
		if (get_button_toggled(&state.hold_center))
		{
			joy_x = 0.0;
			joy_y = 0.0;
			joy_z = 0.0;
		}
		else
		{
			joy_x = ((float)SDL_JoystickGetAxis(joystick, 0) / 32768.0);
			joy_y = (float)SDL_JoystickGetAxis(joystick, 1) / 32768.0;
			joy_z = (float)SDL_JoystickGetAxis(joystick, 2) / 32768.0;
		}
		set_joystick(state.sock, &state.dest, joy_x, joy_y, joy_z);

		usleep(100000);
	}

	return 0;
} /*}}}*/

void display(xplane_state* state) /*{{{*/
{
	// fill the screen with black 
	SDL_FillRect(state->screen, &state->screen->clip_rect, SDL_MapRGB(state->screen->format, 0x00, 0x00, 0x00));

	// widgets
	display_slider(state->screen, &state->throttle);
	display_slider(state->screen, &state->trim);	
	display_slider(state->screen, &state->flaps);	
	display_button(state->screen, &state->hold_center);
	display_button(state->screen, &state->gear_up);
	display_button(state->screen, &state->gear_down);
	display_button(state->screen, &state->brakes);
	display_button(state->screen, &state->center_trim);
	display_button(state->screen, &state->reverse);
	display_text(state->screen, &state->ip);
	//SDL_SaveBMP(state->screen, "/tmp/screen.bmp");
	SDL_Flip(state->screen);
} /*}}}*/
